#include "ST7567.h"
#include "main.h"
#include "image.h"

typedef unsigned char uchar;
typedef unsigned int uint;

// lcd functions
sbit sda  = P1 ^ 0;
sbit sck  = P1 ^ 1;
sbit cd   = P1 ^ 2;
sbit res  = P1 ^ 3;
sbit cs   = P1 ^ 5;

/******************************************************
     write_com(uchar)
     write_dat(uchar)
*******************************************************/
unsigned char i;
// serial 4-SPI???;
void write_com(unsigned char byte)
{
	
	cd = 0;
	//cs = 0;
	
	for (i = 0; i < 8; i++) {
		sck = 0;
		sda = (bit)(byte & 0x80);

		sck = 1;
		byte  <<= 1;
	}
	//cs = 1;

}

// serial 4-SPI???;
void write_dat(unsigned char byte)
{
	//unsigned char i;
	cd = 1;
	//cs = 0;
	
	for (i = 0; i < 8; i++) {
		sck = 0;
		sda = (bit)(byte & 0x80);

		sck = 1;
		byte  <<= 1;
	}
	//cs = 1;
}


void hwReset(void)
{
	res = 0;
	delay_ms(100);
	res = 1;
	delay_ms(10);
}

void icon(uchar da)
{
	uchar j;
	write_com(0xb8);
	write_com(0x10);
	write_com(0x00);
	for (j = 0; j < 132; j++) {
		write_dat(da);
	}
}


void line(uchar da)
{
	uchar i, j;
	for (i = 0xb0; i < 0xb8; i++) {
		write_com(i);
		write_com(0x10);
		write_com(0x00);
		for (j = 0; j < 132; j++) {
			write_dat(da);
		}
	}
}
void ver(unsigned char da, unsigned char db, unsigned char dc, unsigned char dd)
{
	unsigned char i, j;
	for (j = 0; j < 9; j++) {
		write_com(0xb0 + j); // 64???
		write_com(0x10);
		write_com(0x00);
		for (i = 0; i < 33; i++) // 128???,128/4=32
		{
			write_dat(da);
			write_dat(db);
			write_dat(dc);
			write_dat(dd);
		}
	}
}

void cross(unsigned char inv){
	uchar i, j, da;
	da = 0;
	
	for (i = 0xb0; i <= 0xb8; i++) {
		if( (i-0xb0) >= 4) {
			da = 0xff;
		} else {
			da = 0x00;
		}
		
		if(inv) {
			da = ~da;
		}
		
		write_com(i);
		write_com(0x10);
		write_com(0x00);
		
		for (j = 0; j < 132; j++) {
			if(j == 132/2){
				da = ~da;
			}
			write_dat(da);
		}
	}
}

void chess8(unsigned char odd){
	uchar i, j;
	uchar flag = 0;
	uchar initbyte;
	
	for (i = 0xb0; i < 0xb9; i++) {
		if(i%2 == 0){
			initbyte = 0x00;
		} else {
			initbyte = 0xff;
		}
		
		if(odd){
			initbyte = ~initbyte;
		}
		
		write_com(i);
		write_com(0x10);
		write_com(0x00);
		for (j = 0; j < 132; j++) {
			
			if((j>0) && (j%8 == 0)){
				initbyte = ~initbyte;
			}
			write_dat(initbyte);
		}	
	}
}

void ST7567_Init(void)
{
	cs = 0;
	write_com(0xe2); //????
	write_com(0xa2); // 1/9bias
	write_com(0xa1); // seg direction
	write_com(0xc0); // com direction
	write_com(0x25); // resistor ratio(RR)
	write_com(0x81);
	write_com(33); // set V0 output voltage,??????9.41(??9.37-9.39V)
	write_com(0x2f); // power control set
	write_com(0x40); // display start line
	write_com(0xb0); // page address
	write_com(0x10); // column address(msb)
	write_com(0x00); // column address(lsb)
	write_com(0xa4); // normal display
	write_com(0xaf); // display on
}


void lcd_image(unsigned char code *p)
{
    unsigned char i,j;	
	for (i=0xb0;i<0xb9;i++)
	{
	  write_com(i);			// RAM page address
	  write_com(0x10);		// RAM column address most address
	  write_com(0x00);		// RAM column address least address
	  for(j=0;j<132;j++)
	  {
	     write_dat(*p++);
	  }
	}
   
}


void lcdTest(void){
	line(0x11);icon(0x01);
	delay_ms(250);
	

	line(0x22);icon(0x00);
	delay_ms(250);
	

	line(0x44);icon(0x00);
	delay_ms(250);
	

	line(0x88);icon(0x00);
	delay_ms(250);
	

	ver(0xff,0x00,0x00,0x00);delay_ms(250);
	ver(0x00,0xff,0x00,0x00);delay_ms(250);
	ver(0x00,0x00,0xff,0x00);delay_ms(250);
	ver(0x00,0x00,0x00,0xff);delay_ms(250);
	
	lcd_image(image_yes1);
}